package conf

import (
	"errors"
	"fmt"
	"gitee.com/lllgo/gopkg/files"
	"github.com/mitchellh/go-homedir"
	"github.com/spf13/viper"
	"os"
	"path/filepath"
	"strings"
)

var (
	cacheAllConfigAndViper map[string]*viper.Viper
)

func init() {
	cacheAllConfigAndViper = make(map[string]*viper.Viper)
}

func GetHomeDir() string {
	home, _ := homedir.Dir()
	configDir := filepath.Join(home, "."+AppName)
	return configDir
}

func TmpDir() string {
	tmpDir := filepath.Join(GetHomeDir(), "tmp")
	if err := os.MkdirAll(tmpDir, os.ModePerm); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	return tmpDir
}

func ReadAllConfig(path string) error {
	if stat, err := os.Stat(path); err != nil {
		return err
	} else if stat.IsDir() {
		allFile := files.GetAllFile(path, "")
		if len(allFile) > 0 {
			fileType := allFile[0]
			fileType = fileType[strings.LastIndex(fileType, "."):]

			for _, f := range allFile {
				cacheFileAndAllSetting(filepath.Join(path, f))
			}
			return viper.WriteConfigAs(filepath.Join(GetHomeDir(), "all-config"+fileType))
		}

		return errors.New("未找到配置文件")
	}

	cacheFileAndAllSetting(path)
	return nil
}

//缓存所有配置文件和它对应的所有配置
func cacheFileAndAllSetting(path string) {
	v := viper.New()
	v.SetConfigType(path[strings.LastIndex(path, ".")+1:])
	v.SetConfigFile(path)
	if err := v.ReadInConfig(); err != nil {
		panic(fmt.Sprintf("读取文件%s异常 %s", path, err.Error()))
	}
	cacheAllConfigAndViper[path] = v

	var parentKey string
	if len(ConfigPath) < strings.LastIndex(path, "/") {
		parentKey = strings.ReplaceAll(path[len(ConfigPath):strings.LastIndex(path, "/")], "/", ".")
		parentKey = strings.Trim(parentKey, ".")
	}

	for key, val := range v.AllSettings() {
		if parentKey != "" {
			key = parentKey + "." + key
		}
		viper.Set(key, val)
	}

}

func DefaultConfigFile() (inventory, cfg, plugin string) {
	configDir := GetHomeDir()

	// 创建目录
	_, err := os.Stat(configDir)
	if os.IsNotExist(err) {
		err = os.Mkdir(configDir, os.ModePerm)
		if err != nil {
			fmt.Println("create "+configDir+" error", err)
			os.Exit(1)
		}
	}

	// 创建配置文件
	createFile := func(filename string) string {
		i := filepath.Join(configDir, filename)
		_, err = os.Stat(i)
		if os.IsNotExist(err) {
			_, err = os.Create(i)
			if err != nil {
				fmt.Println("create "+i+" error", err)
				os.Exit(1)
			}
		}
		return i
	}

	return createFile("hosts.ini"), createFile("config.yaml"), createFile("plugin.yaml")
}

func Bool(c ConfigBool, def bool) bool {
	if c == nil {
		return def
	}

	if tmp, ok := c.(bool); ok {
		return tmp
	}

	if tmp, ok := c.(string); ok {
		if tmp == "" {
			return def
		}
		return !strings.Contains(FALSE, tmp)
	}

	return false
}
